<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片隐写术工具</title>
    <style>
        /* 基础样式 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background-color: #f5f7fa;
            color: #333;
            transition: background-color 0.3s, color 0.3s;
        }

        body.dark-mode {
            background-color: #121212;
            color: #e0e0e0;
        }

        /* 容器 */
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }

        /* 标题 */
        h1 {
            text-align: center;
            margin-bottom: 30px;
            color: #2c3e50;
            font-size: 2.5em;
        }

        body.dark-mode h1 {
            color: #ffffff;
        }

        /* 模式切换按钮 */
        .mode-toggle {
            position: absolute;
            top: 20px;
            right: 20px;
            padding: 10px 20px;
            background-color: #3498db;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.3s;
        }

        .mode-toggle:hover {
            background-color: #2980b9;
        }

        body.dark-mode .mode-toggle {
            background-color: #2c3e50;
        }

        body.dark-mode .mode-toggle:hover {
            background-color: #34495e;
        }

        /* 标签页 */
        .tabs {
            display: flex;
            margin-bottom: 30px;
            border-bottom: 1px solid #ddd;
        }

        body.dark-mode .tabs {
            border-bottom-color: #333;
        }

        .tab {
            padding: 12px 24px;
            background-color: transparent;
            border: none;
            border-bottom: 2px solid transparent;
            color: #666;
            font-size: 18px;
            cursor: pointer;
            transition: all 0.3s;
        }

        .tab.active {
            border-bottom-color: #3498db;
            color: #3498db;
            font-weight: bold;
        }

        body.dark-mode .tab {
            color: #999;
        }

        body.dark-mode .tab.active {
            color: #3498db;
        }

        /* 功能区 */
        .tab-content {
            display: none;
            background-color: white;
            padding: 30px;
            border-radius: 10px;
            box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
        }

        body.dark-mode .tab-content {
            background-color: #1e1e1e;
            box-shadow: 0 2px 15px rgba(255, 255, 255, 0.05);
        }

        .tab-content.active {
            display: block;
        }

        /* 上传区域 */
        .upload-area {
            border: 2px dashed #3498db;
            border-radius: 10px;
            padding: 40px;
            text-align: center;
            margin-bottom: 20px;
            cursor: pointer;
            transition: all 0.3s;
            background-color: #fafafa;
        }

        body.dark-mode .upload-area {
            border-color: #2980b9;
            background-color: #2a2a2a;
        }

        .upload-area.dragover {
            background-color: #e3f2fd;
            border-color: #2980b9;
            transform: scale(1.02);
        }

        body.dark-mode .upload-area.dragover {
            background-color: #2c3e50;
        }

        .upload-area input[type="file"] {
            display: none;
        }

        /* 文本输入区 */
        .text-area {
            margin-bottom: 20px;
        }

        .text-area label {
            display: block;
            margin-bottom: 10px;
            font-weight: bold;
        }

        .text-area textarea {
            width: 100%;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 5px;
            font-size: 14px;
            resize: vertical;
            min-height: 150px;
            font-family: monospace;
            background-color: white;
            color: #333;
        }

        body.dark-mode .text-area textarea {
            background-color: #333;
            border-color: #555;
            color: #e0e0e0;
        }

        .char-count {
            text-align: right;
            font-size: 12px;
            color: #666;
            margin-top: 5px;
        }

        body.dark-mode .char-count {
            color: #999;
        }

        /* 按钮 */
        .btn {
            background-color: #3498db;
            color: white;
            border: none;
            padding: 12px 30px;
            border-radius: 5px;
            font-size: 16px;
            cursor: pointer;
            margin-right: 10px;
            margin-bottom: 20px;
            transition: background-color 0.3s;
        }

        .btn:hover {
            background-color: #2980b9;
        }

        .btn:disabled {
            background-color: #bdc3c7;
            cursor: not-allowed;
        }

        /* 预览区 */
        .preview-area, .upload-preview {
            margin-bottom: 20px;
        }

        .preview-area img, .upload-preview img {
            max-width: 100%;
            max-height: 400px;
            border-radius: 5px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        }

        /* 上传状态 */
        .upload-status {
            display: block;
            margin-top: 10px;
            color: #27ae60;
            font-size: 14px;
        }

        body.dark-mode .upload-status {
            color: #2ecc71;
        }

        /* 结果区 */
        .result-area {
            margin-top: 20px;
        }

        .result-area label {
            display: block;
            margin-bottom: 10px;
            font-weight: bold;
        }

        .result-area textarea {
            width: 100%;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 5px;
            font-size: 14px;
            resize: vertical;
            min-height: 200px;
            font-family: monospace;
            background-color: white;
            color: #333;
        }

        body.dark-mode .result-area textarea {
            background-color: #333;
            border-color: #555;
            color: #e0e0e0;
        }

        /* 复制按钮 */
        .copy-btn {
            margin-top: 10px;
            padding: 8px 16px;
            background-color: #27ae60;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 14px;
        }

        .copy-btn:hover {
            background-color: #229954;
        }

        /* 错误提示 */
        .error-message {
            color: #e74c3c;
            margin-top: 10px;
            padding: 10px;
            border: 1px solid #e74c3c;
            border-radius: 5px;
            background-color: rgba(231, 76, 60, 0.1);
        }

        body.dark-mode .error-message {
            background-color: rgba(231, 76, 60, 0.2);
            border-color: #c0392b;
        }

        /* 响应式设计 */
        @media (max-width: 768px) {
            h1 {
                font-size: 2em;
            }

            .container {
                padding: 10px;
            }

            .tabs {
                flex-direction: column;
            }

            .tab {
                text-align: left;
            }

            .upload-area {
                padding: 20px;
            }

            .btn {
                width: 100%;
                margin-right: 0;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <button class="mode-toggle" id="modeToggle">切换至暗模式</button>

        <h1>🖼️ 图片隐写术工具</h1>

        <div class="tabs">
            <button class="tab active" data-tab="embed">嵌入信息</button>
            <button class="tab" data-tab="extract">提取信息</button>
        </div>

        <!-- 嵌入功能区 -->
        <div id="embed" class="tab-content active">
            <div class="upload-area" id="embedUpload">
                <input type="file" id="embedFile" accept="image/png,image/jpeg" />
                <div>点击或拖拽上传图片 (PNG/JPG, 最大5MB)</div>
                <span class="upload-status" id="embedUploadStatus"></span>
            </div>
            <div class="upload-preview" id="embedUploadPreview"></div>

            <div class="text-area">
                <label for="embedText">输入秘密信息：</label>
                <textarea id="embedText" placeholder="请输入要隐藏的文本..."></textarea>
                <div class="char-count" id="charCount">0 字符</div>
            </div>

            <button class="btn" id="embedBtn">生成隐写图片</button>

            <div class="preview-area" id="embedPreview"></div>

            <div id="embedResult"></div>
        </div>

        <!-- 提取功能区 -->
        <div id="extract" class="tab-content">
            <div class="upload-area" id="extractUpload">
                <input type="file" id="extractFile" accept="image/png,image/jpeg" />
                <div>点击或拖拽上传包含隐藏信息的图片</div>
                <span class="upload-status" id="extractUploadStatus"></span>
            </div>

            <button class="btn" id="extractBtn">提取秘密信息</button>

            <div class="result-area" id="extractResult"></div>
        </div>
    </div>

    <script>
        // 标签页切换
        document.querySelectorAll('.tab').forEach(tab => {
            tab.addEventListener('click', () => {
                const targetTab = tab.dataset.tab;

                document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
                document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));

                tab.classList.add('active');
                document.getElementById(targetTab).classList.add('active');
            });
        });

        // 明暗模式切换
        const modeToggle = document.getElementById('modeToggle');
        const body = document.body;

        modeToggle.addEventListener('click', () => {
            if (body.classList.contains('dark-mode')) {
                body.classList.remove('dark-mode');
                modeToggle.textContent = '切换至暗模式';
                localStorage.setItem('darkMode', 'false');
            } else {
                body.classList.add('dark-mode');
                modeToggle.textContent = '切换至明模式';
                localStorage.setItem('darkMode', 'true');
            }
        });

        // 初始化模式
        if (localStorage.getItem('darkMode') === 'true') {
            body.classList.add('dark-mode');
            modeToggle.textContent = '切换至明模式';
        }

        // 拖拽上传功能
        const uploadAreas = document.querySelectorAll('.upload-area');
        const embedFileInput = document.getElementById('embedFile');
        const extractFileInput = document.getElementById('extractFile');

        // 嵌入功能：上传预览和状态
        const embedUploadStatus = document.getElementById('embedUploadStatus');
        const embedUploadPreview = document.getElementById('embedUploadPreview');
        const embedResult = document.getElementById('embedResult');

        // 创建结果预览区域
        const embedResultPreview = document.createElement('div');
        embedResultPreview.className = 'preview-area';
        embedResultPreview.id = 'embedResultPreview';
        embedResult.parentNode.insertBefore(embedResultPreview, embedResult);

        // 提取功能：上传预览和状态
        const extractUploadStatus = document.getElementById('extractUploadStatus');
        const extractPreview = document.createElement('div');
        extractPreview.className = 'preview-area';
        const extractUpload = document.getElementById('extractUpload');
        extractUpload.parentNode.insertBefore(extractPreview, extractUpload.nextSibling);

        // 显示上传预览和状态
        function showUploadPreview(fileInput, statusElement, previewArea) {
            const file = fileInput.files[0];
            if (file) {
                // 显示上传状态
                statusElement.textContent = `已上传：${file.name} (${(file.size / 1024 / 1024).toFixed(2)}MB)`;

                // 显示上传预览
                const imgURL = URL.createObjectURL(file);
                previewArea.innerHTML = `<img src="${imgURL}" alt="上传图片预览" />`;
            }
        }

        uploadAreas.forEach(area => {
            area.addEventListener('dragover', (e) => {
                e.preventDefault();
                area.classList.add('dragover');
            });

            area.addEventListener('dragleave', () => {
                area.classList.remove('dragover');
            });

            area.addEventListener('drop', (e) => {
                e.preventDefault();
                area.classList.remove('dragover');

                const files = e.dataTransfer.files;
                if (files.length > 0) {
                    const fileInput = area.querySelector('input[type="file"]');
                    fileInput.files = files;

                    // 根据不同区域显示不同预览和状态
                    if (fileInput.id === 'embedFile') {
                        showUploadPreview(fileInput, embedUploadStatus, embedUploadPreview);
                    } else if (fileInput.id === 'extractFile') {
                        showUploadPreview(fileInput, extractUploadStatus, extractPreview);
                    }
                }
            });

            area.addEventListener('click', () => {
                const fileInput = area.querySelector('input[type="file"]');
                fileInput.click();
            });
        });

        // 嵌入功能：文件选择预览
        embedFileInput.addEventListener('change', () => {
            showUploadPreview(embedFileInput, embedUploadStatus, embedUploadPreview);
        });

        // 提取功能：文件选择预览
        extractFileInput.addEventListener('change', () => {
            showUploadPreview(extractFileInput, extractUploadStatus, extractPreview);
        });

        // 字符计数
        const embedText = document.getElementById('embedText');
        const charCount = document.getElementById('charCount');

        embedText.addEventListener('input', () => {
            const count = embedText.value.length;
            charCount.textContent = `${count} 字符`;
        });

        // 嵌入功能：生成隐写图片
        const embedBtn = document.getElementById('embedBtn');

        embedBtn.addEventListener('click', async () => {
            const file = embedFileInput.files[0];
            const text = embedText.value.trim();

            if (!file) {
                showError(embedResult, '请先上传图片');
                return;
            }

            if (!text) {
                showError(embedResult, '请输入要隐藏的文本');
                return;
            }

            if (file.size > 5 * 1024 * 1024) {
                showError(embedResult, '图片大小不能超过5MB');
                return;
            }

            embedBtn.disabled = true;
            embedResult.innerHTML = '';
            // 清空之前的结果预览
            document.getElementById('embedResultPreview').innerHTML = '';

            const formData = new FormData();
            formData.append('image', file);
            formData.append('text', text);

            try {
                const response = await fetch('/embed', {
                    method: 'POST',
                    body: formData
                });

                if (response.ok) {
                    const blob = await response.blob();
                    const imgURL = URL.createObjectURL(blob);

                    // 在结果预览区域显示隐写图片
                    document.getElementById('embedResultPreview').innerHTML = `<img src="${imgURL}" alt="隐写图片" />`;

                    const downloadLink = document.createElement('a');
                    downloadLink.href = imgURL;
                    downloadLink.download = `stego_${file.name}`;
                    downloadLink.className = 'btn';
                    downloadLink.textContent = '下载隐写图片';

                    embedResult.appendChild(downloadLink);
                } else {
                    const errorData = await response.json();
                    showError(embedResult, errorData.error);
                }
            } catch (error) {
                showError(embedResult, '操作失败，请重试');
            } finally {
                embedBtn.disabled = false;
            }
        });

        // 提取功能
        const extractBtn = document.getElementById('extractBtn');
        const extractResult = document.getElementById('extractResult');

        extractBtn.addEventListener('click', async () => {
            const file = extractFileInput.files[0];

            if (!file) {
                showError(extractResult, '请先上传图片');
                return;
            }

            extractBtn.disabled = true;
            extractResult.innerHTML = '';

            const formData = new FormData();
            formData.append('image', file);

            try {
                const response = await fetch('/extract', {
                    method: 'POST',
                    body: formData
                });

                if (response.ok) {
                    const data = await response.json();

                    const resultDiv = document.createElement('div');
                    resultDiv.innerHTML = `
                        <div class="result-area">
                            <label>提取的秘密信息：</label>
                            <textarea id="extractedText" readonly>${data.text}</textarea>
                            <button class="copy-btn" onclick="copyToClipboard()">复制文本</button>
                        </div>
                    `;

                    extractResult.appendChild(resultDiv);
                } else {
                    const errorData = await response.json();
                    showError(extractResult, errorData.error);
                }
            } catch (error) {
                showError(extractResult, '操作失败，请重试');
            } finally {
                extractBtn.disabled = false;
            }
        });

        // 复制到剪贴板
        function copyToClipboard() {
            const textarea = document.getElementById('extractedText');
            textarea.select();
            document.execCommand('copy');
            alert('已复制到剪贴板');
        }

        // 显示错误信息
        function showError(container, message) {
            container.innerHTML = `<div class="error-message">${message}</div>`;
        }
    </script>
</body>
</html>
